﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using ZenSystemService.Api.Data;
using ZenSystemService.Api.DTOs;
using ZenSystemService.Api.DTOs.ProductType;
using ZenSystemService.Api.DTOs.TrainingItem;
using ZenSystemService.Api.Entities;
using ZenSystemService.Api.Exceptions;
using ZenSystemService.Api.Utils;

namespace ZenSystemService.Api.Services
{
    public class InstitutionTrainingItemService
    {
        private readonly ApplicationDbContext _context;
        private readonly IMapper _mapper;

        public InstitutionTrainingItemService(ApplicationDbContext context, IMapper mapper)
        {
            _context = context;
            _mapper = mapper;
        }

        public async Task<IEnumerable<TrainingItemQueryResultDTO>> GetAllTrainingItemsAsync(ReceiveObject req)
        {
            string orderBy = req.Order;
            var splited = orderBy.Split(' ');
            var orderField = "";
            var orderMethod = "";
            if (splited.Length > 0)
            {
                orderField = $"{splited[0]}";
            }
            if (splited.Length > 1)
            {
                orderMethod = splited[1];
            }

            var trainingItems = _context.TrainingItems.Include(t => t.Institution)
                .Include(t => t.ProductType)
                .Include(t => t.DeviceType).AsQueryable();
            var predicates = req.Where.GeneratePredicates<TrainingItem>();
            foreach (var predicate in predicates)
            {
                trainingItems = trainingItems.Where(predicate);
            }
            //if (!string.IsNullOrEmpty(orderBy))
            //    trainingItems = trainingItems.OrderBy(orderField);
            int index = (req.Page - 1 < 0 ? 0 : req.Page - 1) * req.PageSize;
            trainingItems = trainingItems.Skip(index).Take(req.PageSize);
            return _mapper.Map<IEnumerable<TrainingItemQueryResultDTO>>(trainingItems);
        }

        public async Task<TrainingItemQueryResultDTO?> GetTraingItemByIdAsync(int id)
        {
            var traingingItem = await _context.TrainingItems.Include(t => t.Institution)
                .Include(t => t.ProductType)
                .Include(t => t.DeviceType)
                .FirstOrDefaultAsync(p => p.TrainingItemId == id);
            if (traingingItem != null)
            {
                return _mapper.Map<TrainingItemQueryResultDTO>(traingingItem);
            }
            return null;
        }

        public async Task<TrainingItemQueryResultDTO> CreateTrainingItemAsync(
            TrainingItemCreateRequestDTO trainingItem)
        {
            var existed = await _context.ProductTypes.AnyAsync(pt => pt.Alias == trainingItem.Name);
            if (existed)
                throw new ConflictException($"{ trainingItem.Name } 是保留名字，请使用其他名字");
            var trainingItemEntity = _mapper.Map<TrainingItem>(trainingItem);
            //var deviceType = await _context.DeviceTypes.FirstOrDefaultAsync(d => d. == trainingItem.DeviceTypeId);
            await _context.TrainingItems.AddAsync(trainingItemEntity);
            _context.SaveChanges();
            return _mapper.Map<TrainingItemQueryResultDTO>(trainingItemEntity);
        }

        public async Task<ProductTypeQueryResultDTO> UpdateProductTypeAsync(ProductTypeUpdateRequestDTO productType)
        {
            var productTypeEntity = await _context.ProductTypes.FirstOrDefaultAsync(t => t.ProductTypeId == productType.ProductTypeId);
            if (productTypeEntity == null)
            {
                return null;
            }
            productTypeEntity.UpdateFrom(productType);
            _context.Entry(productTypeEntity).State = EntityState.Modified;
            int count = await _context.SaveChangesAsync();
            return _mapper.Map<ProductTypeQueryResultDTO>(productTypeEntity);
        }

        public async Task<bool> DeleteProductTypeAsync(int id)
        {
            var deviceType = await _context.ProductTypes.FindAsync(id);
            if (deviceType != null)
            {
                _context.ProductTypes.Remove(deviceType);
                int count = await _context.SaveChangesAsync();
                return count > 0 ? true : false;
            }
            else
            {
                return false;
            }
        }
    }
}
   